home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / dsort / dstqsrt.asm < prev    next >
Assembly Source File  |  1993-07-08  |  7KB  |  232 lines

  1.     page    96,132
  2. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  3. ;§                                                                          §
  4. ;§              ディレクトリエントリ  ソート  ユーティリティ                §
  5. ;§                                                                          §
  6. ;§                                     DSORT.EXE  Ver1.30    §
  7. ;§                                                                          §
  8. ;§              Copyright (C) by 福地 邦雄 1991-1992. All rights reserved.  §
  9. ;§∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞§
  10.     .MODEL  SMALL,C
  11. ;
  12. REVERSE     equ 1
  13. FALSE       equ 0
  14. direntrysize    equ 20h
  15. direntryseg     equ 2
  16. ;
  17.     public  dirqsort,dirswap,sortfuncall
  18. ;
  19.     .code
  20. ;
  21. ;------------------------------------------------------------------------------
  22. ;
  23. ;   dirqsort
  24. ;       ディレクトリエントリのクイックソート
  25. ;
  26. ;   TYPE    near call
  27. ;   IN      [SP+2] = ソートバッファセグメント
  28. ;           [SP+4] = 要素数
  29. ;           ES:[SP+6] = 比較関数リストアドレス
  30. ;   OUT     なし
  31. ;   保存レジスタ    bp,ds
  32. ;
  33. ;------------------------------------------------------------------------------
  34. ;
  35. dirqsort    proc    sortobj,elmcount,funclist
  36.     local cmpobj,chgedobj,cmpcount,chgcount,funcseg
  37. ;
  38.     mov     funcseg,es
  39. qsorthead:
  40.     cmp     elmcount,1
  41. ;   @if (zf,off),and,(cf,off),L     ; 要素数2以上ならソート実行
  42.       jz    @i0001
  43.       jnc   @i0002
  44. @i0001:
  45.       jmp   @i0003
  46. @i0002:
  47.         mov     dx,sortobj
  48.         add     dx,direntryseg
  49.         cmp     elmcount,02
  50.         mov     cmpobj,dx
  51. ;       @if (zf,on)                 ; 要素数2なら直接比較
  52.           jnz   @i0004
  53.             mov     bx,funclist
  54.             mov     es,funcseg
  55.             mov     ds,sortobj
  56.             call    sortfuncall
  57.             test    ax,ax
  58. ;           @if (zf,off),and,(sf,off)   ; エントリ1が大きい時は入れ換え
  59.               jz    @i0005
  60.               js    @i0005
  61.                 mov     es,cmpobj
  62.                 mov     ds,sortobj
  63.                 call    dirswap
  64. ;           @ifend
  65. @i0005:
  66. ;       @else                       ; 要素数3以上
  67.           jmp   @i0006
  68. @i0004:
  69.             mov     ax,elmcount     ; 比較の基準を配列の真ん中から取り出す
  70.             and     ax,0fffeh
  71.             add     ax,sortobj
  72.             mov     es,ax
  73.             mov     ds,sortobj
  74.             call    dirswap
  75.             mov     ax,sortobj      ; 準備
  76.             mov     chgcount,0
  77.             mov     cmpcount,1
  78.             mov     chgedobj,ax
  79. ;           @do repeat
  80. @d0001:
  81.                 mov     ax,cmpcount ; 比較終了か?
  82. ;               @if (ax,>=,elmcount)
  83.                   cmp   ax,elmcount
  84.                   jb    @i0007
  85. ;                   @doexit
  86.                       jmp   @d0002
  87. ;               @ifend
  88. @i0007:
  89.                 mov     dx,sortobj  ; 比較関数呼び出し
  90.                 mov     ds,cmpobj
  91.                 mov     bx,funclist
  92.                 mov     es,funcseg
  93.                 call    sortfuncall
  94.                 test    ax,ax
  95. ;               @if (sf,on)         ; 比較対象エントリが小さい時
  96.                   jns   @i0008
  97.                     inc     chgcount
  98.                     add     chgedobj,direntryseg
  99.                     mov     si,cmpobj
  100.                     mov     es,si
  101.                     mov     di,chgedobj
  102.                     mov     ds,di
  103. ;                   @if (si,/=,di)
  104.                       cmp   si,di
  105.                       je    @i0009
  106.                         call      dirswap
  107. ;                   @ifend
  108. @i0009:
  109. ;               @ifend
  110. @i0008:
  111.                 add     cmpobj,direntryseg  ; 次の比較対象へ
  112.                 inc     cmpcount
  113. ;           @doend
  114.               jmp   @d0001
  115. @d0002:
  116.             mov     di,sortobj      ;
  117.             mov     ds,di
  118.             mov     si,chgedobj
  119.             mov     es,si
  120. ;           @if (si,/=,di)
  121.               cmp   si,di
  122.               je    @i0010
  123.                 call      dirswap
  124. ;           @ifend
  125. @i0010:
  126.             mov     bx,chgedobj     ; 再帰呼び出し準備
  127.             add     bx,direntryseg
  128.             mov     cx,elmcount
  129.             mov     ax,chgcount
  130.             sub     cx,ax
  131.             dec     cx
  132. ;           @if (cx,>,ax),S         ; エントリ数の少ない方によって環境を整える
  133.               cmp   cx,ax
  134.               jbe   @i0011
  135.                 mov     elmcount,cx ; 入れ換え済の方が少ない
  136.                 mov     cx,ax
  137.                 xchg    bx,sortobj
  138. ;           @else
  139.               jmp short @i0012
  140. @i0011:
  141.                 mov     elmcount,ax ; 入れ換え無しの方が少ない
  142. ;           @ifend
  143. @i0012:
  144. ;           @if (cx,>,1)            ; 要素数2以上なら
  145.               cmp   cx,1
  146.               jbe   @i0013
  147.                 mov     es,funcseg  ;
  148.                 push    funclist    ; 再帰呼び出し(エントリの少ない方)
  149.                 push    cx
  150.                 push    bx
  151.                 call    dirqsort
  152. ;           @ifend
  153. @i0013:
  154.             jmp     qsorthead       ; 末尾再帰呼び出し(ループ)
  155. ;       @ifend
  156. @i0006:
  157. ;   @ifend
  158. @i0003:
  159.     ret     6
  160. ;
  161. dirqsort    endp
  162. ;
  163. ;------------------------------------------------------------------------------
  164. ;
  165. ;   dirswap
  166. ;       ディレクトリエントリの交換
  167. ;
  168. ;   TYPE    near call
  169. ;   IN      DS:0  = エントリ1アドレス
  170. ;           ES:0  = エントリ2アドレス
  171. ;   OUT     なし
  172. ;   保存レジスタ    bx,dx,di,bp,ds,es
  173. ;
  174. ;------------------------------------------------------------------------------
  175. ;
  176. dirswap proc
  177. ;
  178.     mov     cx,direntrysize/2
  179.     xor     si,si
  180. swaploop:
  181.     mov     ax,[si]
  182.     xchg    es:[si],ax
  183.     mov     [si],ax
  184.     lea     si,[si+2]
  185.     loop    swaploop
  186. ;
  187.     ret
  188. ;
  189. dirswap endp
  190. ;
  191. ;------------------------------------------------------------------------------
  192. ;
  193. ;   sortfuncall
  194. ;       ソート用比較関数列の呼び出し
  195. ;
  196. ;   TYPE    near call
  197. ;   IN      ES:BX = 比較関数列のアドレス
  198. ;           DS:0  = エントリ1アドレス
  199. ;           DX:0  = エントリ2アドレス
  200. ;   OUT     AX = 比較結果
  201. ;   保存レジスタ    si,di,bp,ds,es
  202. ;
  203. ;------------------------------------------------------------------------------
  204. ;
  205. sortfuncall proc
  206. ;
  207. ;   @do until
  208. @d0003:
  209.         call    word ptr es:[bx]    ; 比較関数呼び出し
  210. ;       @if (word ptr es:[bx+2],=,REVERSE)  ; 逆順指定の時は結果を反転
  211.           cmp   word ptr es:[bx+2],REVERSE
  212.           jne   @i0014
  213.             neg     ax
  214. ;       @ifend
  215. @i0014:
  216. ;       @if (ax,/=,0)               ; 比較して違いがあれば終了
  217.           or    ax,ax
  218.           je    @i0015
  219.             jmp     compareend
  220. ;       @ifend
  221. @i0015:
  222.         lea     bx,[bx+4]           ; 次の比較関数へ
  223. ;   @doend (word ptr es:[bx],=,0)   ; 関数列の終了まで
  224.       cmp   word ptr es:[bx],0
  225.       jne   @d0003
  226. compareend:
  227.     ret
  228. ;
  229. sortfuncall endp
  230. ;
  231.     end
  232.